from datetime import datetime
from typing import Optional
from bson import ObjectId
from pydantic import BaseModel, field_validator, Field

from app.models.task_enum import TaskStatus


class TaskListQueryModel(BaseModel):
    status: Optional[str] = TaskStatus.ALL.value  # 接收来自请求的原始字符串

    @field_validator('status')
    @classmethod
    def validate_status(cls, v):
        if v is None:
            return TaskStatus.ALL.value
        # 验证是否为有效的枚举值
        try:
            TaskStatus(v)  # 验证是否为有效枚举值
            return v  # 返回原始字符串
        except ValueError:
            raise ValueError(
                f"status must be one of: {[e.value for e in TaskStatus]}")

    def get_status_enum(self) -> TaskStatus:
        """获取枚举对象"""
        return TaskStatus(self.status or TaskStatus.ALL.value)


class TaskModel(BaseModel):
    _id: Optional[ObjectId] = None
    id: Optional[int] = None
    title: str
    description: Optional[str] = None
    status: str = TaskStatus.PENDING.value
    created_at: Optional[datetime] = None
    updated_at: Optional[datetime] = None

class NewTaskModel(BaseModel):
    title: str
    description: Optional[str] = None
    status: str = TaskStatus.PENDING.value
    
    # 使用 Field 的 default_factory 自动生成时间戳
    created_at: datetime = Field(default_factory=datetime.now)
    updated_at: datetime = Field(default_factory=datetime.now)

class UpdateTaskModel(BaseModel):
    title: Optional[str] = None
    description: Optional[str] = None
    status: Optional[str] = None
    
    # 更新时间戳（只在有字段更新时设置）
    updated_at: datetime = Field(default_factory=datetime.now)
    
    @field_validator('status')
    @classmethod
    def validate_status(cls, v):
        if v is not None:
            try:
                TaskStatus(v)  # 验证是否为有效枚举值
                return v
            except ValueError:
                raise ValueError(f"status must be one of: {[e.value for e in TaskStatus]}")
        return v
    
    def has_updates(self) -> bool:
        """检查是否有实际的更新字段"""
        return any([
            self.title is not None,
            self.description is not None, 
            self.status is not None
        ])
    
    def get_update_dict(self, exclude_none: bool = True) -> dict:
        """获取用于更新的字典，可选择排除 None 值"""
        return self.model_dump(exclude_none=exclude_none)